package com.marketing.tenant.controller;

import com.marketing.common.Result;
import com.marketing.tenant.annotation.RequirePermission;
import com.marketing.tenant.entity.TenantUsage;
import com.marketing.tenant.service.TenantUsageService;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.responses.ApiResponse;
import io.swagger.v3.oas.annotations.responses.ApiResponses;
import io.swagger.v3.oas.annotations.security.SecurityRequirement;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.web.bind.annotation.*;

import java.time.LocalDate;
import java.util.List;
import java.util.Map;

/**
 * 租户使用统计控制器
 */
@RestController
@RequestMapping("/api/tenant-usage")
@Tag(name = "使用统计", description = "租户资源使用统计、API调用量、存储使用量等数据分析")
@SecurityRequirement(name = "Bearer Authentication")
public class TenantUsageController {

    private static final Logger log = LoggerFactory.getLogger(TenantUsageController.class);

    @Autowired
    private TenantUsageService tenantUsageService;

    /**
     * 获取租户指定日期的使用统计
     */
    @GetMapping("/tenant/{tenantId}/date/{statDate}")
    @RequirePermission(value = {"tenant:usage:view", "tenant:manage"}, description = "查看租户使用统计")
    @Operation(summary = "获取指定日期使用统计", description = "获取租户在指定日期的资源使用统计数据")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功"),
            @ApiResponse(responseCode = "401", description = "未授权"),
            @ApiResponse(responseCode = "403", description = "权限不足")
    })
    public Result<TenantUsage> getTenantUsage(
            @Parameter(description = "租户ID", required = true) @PathVariable Long tenantId,
            @Parameter(description = "统计日期，格式: yyyy-MM-dd", required = true, example = "2024-01-15")
            @PathVariable @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate statDate) {
        log.info("获取租户使用统计: tenantId={}, date={}", tenantId, statDate);
        
        try {
            TenantUsage usage = tenantUsageService.getTenantUsage(tenantId, statDate);
            return Result.success(usage);
        } catch (Exception e) {
            log.error("获取租户使用统计失败: tenantId={}, date={}", tenantId, statDate, e);
            return Result.error("获取使用统计失败: " + e.getMessage());
        }
    }

    /**
     * 获取租户最近N天的使用统计
     */
    @GetMapping("/tenant/{tenantId}/recent")
    @RequirePermission(value = {"tenant:usage:view", "tenant:manage"}, description = "查看租户使用统计")
    @Operation(summary = "获取最近使用统计", description = "获取租户最近N天的资源使用统计数据")
    @ApiResponses(value = {
            @ApiResponse(responseCode = "200", description = "查询成功"),
            @ApiResponse(responseCode = "401", description = "未授权"),
            @ApiResponse(responseCode = "403", description = "权限不足")
    })
    public Result<List<TenantUsage>> getRecentTenantUsage(
            @Parameter(description = "租户ID", required = true) @PathVariable Long tenantId,
            @Parameter(description = "统计天数", example = "7") @RequestParam(defaultValue = "7") Integer days) {
        log.info("获取租户最近使用统计: tenantId={}, days={}", tenantId, days);
        
        try {
            List<TenantUsage> usageList = tenantUsageService.getRecentTenantUsage(tenantId, days);
            return Result.success(usageList);
        } catch (Exception e) {
            log.error("获取租户最近使用统计失败: tenantId={}, days={}", tenantId, days, e);
            return Result.error("获取使用统计失败: " + e.getMessage());
        }
    }

    /**
     * 获取租户使用统计摘要
     */
    @GetMapping("/tenant/{tenantId}/summary")
    @RequirePermission(value = {"tenant:usage:view", "tenant:manage"}, description = "查看租户使用统计")
    public Result<Map<String, Object>> getTenantUsageSummary(@PathVariable Long tenantId,
                                                            @RequestParam(defaultValue = "30") Integer days) {
        log.info("获取租户使用统计摘要: tenantId={}, days={}", tenantId, days);
        
        try {
            Map<String, Object> summary = tenantUsageService.getTenantUsageSummary(tenantId, days);
            return Result.success(summary);
        } catch (Exception e) {
            log.error("获取租户使用统计摘要失败: tenantId={}, days={}", tenantId, days, e);
            return Result.error("获取使用统计摘要失败: " + e.getMessage());
        }
    }

    /**
     * 获取系统使用统计报告
     */
    @GetMapping("/system/report")
    @RequirePermission(value = {"system:usage:view", "tenant:manage"}, description = "查看系统使用统计")
    public Result<Map<String, Object>> getSystemUsageReport(
            @RequestParam(required = false) @DateTimeFormat(pattern = "yyyy-MM-dd") LocalDate statDate) {
        
        if (statDate == null) {
            statDate = LocalDate.now().minusDays(1); // 默认查看昨天的数据
        }
        
        log.info("获取系统使用统计报告: date={}", statDate);
        
        try {
            Map<String, Object> report = tenantUsageService.getSystemUsageReport(statDate);
            return Result.success(report);
        } catch (Exception e) {
            log.error("获取系统使用统计报告失败: date={}", statDate, e);
            return Result.error("获取系统统计报告失败: " + e.getMessage());
        }
    }

    /**
     * 手动记录API调用（主要用于测试）
     */
    @PostMapping("/tenant/{tenantId}/api-call")
    @RequirePermission(value = {"tenant:usage:record", "tenant:manage"}, description = "记录租户使用统计")
    public Result<Void> recordApiCall(@PathVariable Long tenantId,
                                      @RequestParam(defaultValue = "1") Long count) {
        log.info("记录API调用: tenantId={}, count={}", tenantId, count);
        
        try {
            boolean success = tenantUsageService.recordApiCall(tenantId, count);
            if (success) {
                return Result.success(null, "API调用记录成功");
            } else {
                return Result.error("API调用记录失败");
            }
        } catch (Exception e) {
            log.error("记录API调用失败: tenantId={}, count={}", tenantId, count, e);
            return Result.error("记录API调用失败: " + e.getMessage());
        }
    }

    /**
     * 手动记录用户登录（主要用于测试）
     */
    @PostMapping("/tenant/{tenantId}/login")
    @RequirePermission(value = {"tenant:usage:record", "tenant:manage"}, description = "记录租户使用统计")
    public Result<Void> recordLogin(@PathVariable Long tenantId,
                                    @RequestParam(defaultValue = "1") Integer count) {
        log.info("记录用户登录: tenantId={}, count={}", tenantId, count);
        
        try {
            boolean success = tenantUsageService.recordLogin(tenantId, count);
            if (success) {
                return Result.success(null, "用户登录记录成功");
            } else {
                return Result.error("用户登录记录失败");
            }
        } catch (Exception e) {
            log.error("记录用户登录失败: tenantId={}, count={}", tenantId, count, e);
            return Result.error("记录用户登录失败: " + e.getMessage());
        }
    }

    /**
     * 更新存储使用量
     */
    @PutMapping("/tenant/{tenantId}/storage")
    @RequirePermission(value = {"tenant:usage:update", "tenant:manage"}, description = "更新租户使用统计")
    public Result<Void> updateStorageUsage(@PathVariable Long tenantId,
                                           @RequestParam Long storageUsed) {
        log.info("更新存储使用量: tenantId={}, storageUsed={}", tenantId, storageUsed);
        
        try {
            boolean success = tenantUsageService.updateStorageUsage(tenantId, storageUsed);
            if (success) {
                return Result.success(null, "存储使用量更新成功");
            } else {
                return Result.error("存储使用量更新失败");
            }
        } catch (Exception e) {
            log.error("更新存储使用量失败: tenantId={}, storageUsed={}", tenantId, storageUsed, e);
            return Result.error("更新存储使用量失败: " + e.getMessage());
        }
    }

    /**
     * 更新用户统计
     */
    @PutMapping("/tenant/{tenantId}/users")
    @RequirePermission(value = {"tenant:usage:update", "tenant:manage"}, description = "更新租户使用统计")
    public Result<Void> updateUserStats(@PathVariable Long tenantId,
                                        @RequestParam Integer userCount,
                                        @RequestParam Integer activeUserCount) {
        log.info("更新用户统计: tenantId={}, userCount={}, activeUserCount={}", tenantId, userCount, activeUserCount);
        
        try {
            boolean success = tenantUsageService.updateUserStats(tenantId, userCount, activeUserCount);
            if (success) {
                return Result.success(null, "用户统计更新成功");
            } else {
                return Result.error("用户统计更新失败");
            }
        } catch (Exception e) {
            log.error("更新用户统计失败: tenantId={}, userCount={}, activeUserCount={}", tenantId, userCount, activeUserCount, e);
            return Result.error("更新用户统计失败: " + e.getMessage());
        }
    }

    /**
     * 初始化今日使用统计
     */
    @PostMapping("/tenant/{tenantId}/init-today")
    @RequirePermission(value = {"tenant:usage:create", "tenant:manage"}, description = "初始化租户使用统计")
    public Result<Void> initTodayUsage(@PathVariable Long tenantId) {
        log.info("初始化今日使用统计: tenantId={}", tenantId);
        
        try {
            boolean success = tenantUsageService.initTodayUsage(tenantId);
            if (success) {
                return Result.success(null, "今日使用统计初始化成功");
            } else {
                return Result.error("今日使用统计初始化失败");
            }
        } catch (Exception e) {
            log.error("初始化今日使用统计失败: tenantId={}", tenantId, e);
            return Result.error("初始化今日使用统计失败: " + e.getMessage());
        }
    }
}